package com.jn.erp.web.api.student.controller;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.jn.erp.common.annotation.Log;
import com.jn.erp.common.core.page.TableDataInfo;
import com.jn.erp.common.core.result.AjaxResult;
import com.jn.erp.common.enums.BusinessType;
import com.jn.erp.security.controller.BaseWebAuthController;
import com.jn.erp.web.api.student.entity.*;
import com.jn.erp.web.api.student.entity.dto.EnrollmentStuDto;
import com.jn.erp.web.api.student.entity.dto.StudentBaseInfoDTO;
import com.jn.erp.web.api.student.entity.vo.StudentCourseVo;
import com.jn.erp.web.api.student.enums.StudentStageEnum;
import com.jn.erp.web.api.student.service.*;
import com.jn.erp.web.api.student.utils.EnumTools;
import com.jn.erp.web.api.student.utils.ImportExportService;
import com.jn.erp.web.api.student.utils.UserAuthUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@RestController
@RequestMapping("/student")
@Api(value = "学生管理", tags = "学生管理")
public class StudentController extends BaseWebAuthController {

    @Autowired
    private StudentService studentService;

    @Autowired
    private ImportExportService importExportService;

    @Autowired
    private com.jn.erp.web.api.student.service.ClassService classService;

    @Autowired
    private ClassGradeService classGradeService;

    @Autowired
    private StudentCourseService studentCourseService;


    @Autowired
    private StudentContactRecordService studentContactRecordService;

    @Autowired
    private StudentClassService studentClassService;

    //导入 , 时间格式

    // 在读学员2 历史5 线索1
    @ApiOperation("学员列表")
    @GetMapping("/list")
    public TableDataInfo studentList(Student student) {
        // 机构id报读
        student.setOrgId(Long.parseLong(loginDeptAuth()));
        // 前端传 2-- 在读学员  5 -- 历史学员
        startPage();
        student.setDeleted(0);
        List<Student> list = studentService.getList(student);
        TableDataInfo dataTable = getDataTable(list);
        // 没有跟进人 线索学员 1
        return dataTable;
    }

    /**
     * 学员详情回显接口
     */
    @PostMapping("/getStudent")
    public AjaxResult getStudent(@RequestBody Student student) {
        // 机构id报读
        student.setOrgId(Long.parseLong(loginDeptAuth()));
        Student stu = studentService.getStudent(student);
        return success(stu);
    }


    /**
     * 编辑新增学员基本信息
     *
     * @param studentDTO
     * @return
     */
    @Log(title = "编辑新增学员基本信息", businessType = BusinessType.UPDATE)
    @PostMapping("/save")
    public AjaxResult saveStudent(@RequestBody StudentBaseInfoDTO studentDTO) {
        //        获取登录者信息
        studentDTO.setOrgId(Long.parseLong(loginDeptAuth()));
        Long stu = studentService.studentUnifysaveOrUpdateByDTO(studentDTO);
        return AjaxResult.success(stu);

    }

    /**
     * 学员报名
     */
// tCourse/list
    @Log(title = "学员报名")
    @PostMapping("/application")
    public AjaxResult saveCourse(@RequestBody StudentCourseVo studentCourseVo) {
        List<StudentCourse> sc = studentCourseService.addOne(studentCourseVo);
            return success(sc);
    }

    /**
     * 模糊查询报名上课学员
     * @param student
     * @return
     */
    @PostMapping("/allStudent")
    public AjaxResult allStudent(@RequestBody Student student) {
        student.setOrgId(Long.parseLong(loginDeptAuth()));
        List<Student> stu = studentService.allStudent(student);
        return success(stu);
    }

    /**
     * 全部学员
     * @param student
     * @return
     */
    @PostMapping("/allStudentList")
    public AjaxResult allStudentList(@RequestBody Student student) {
        student.setOrgId(Long.parseLong(loginDeptAuth()));
        List<Student> stu = studentService.studentList(student);
        return success(stu);
    }

    /**
     * 删除跟进记录
     *
     * @param
     * @return
     */
    @PostMapping("/applicationDelete")
    public AjaxResult applicationDelete(@RequestBody StudentCourse studentCourse) {
        long id = studentCourse.getId();
        StudentCourse byId = studentCourseService.getById(id);
        byId.setDeleted(1);
        studentCourseService.updateById(byId);
        return AjaxResult.success("删除成功");
    }


    /**
     * 报名回显接口
     * 前端传学生id
     *
     * @param
     * @return
     */
    @PostMapping("/applicationOne")
    public AjaxResult applicationOne(@RequestBody Student student) {
        student.setOrgId(Long.parseLong(loginDeptAuth()));
        Student stu = studentService.applicationOne(student);
        if (stu == null) {
            return success("暂无数据");
        }
        return AjaxResult.success(stu);
    }


    // 历史学员转换成在读学员
    @PostMapping("/changeLearning")
    public AjaxResult changeLearning(@RequestBody Student student) {
        //2 是 在学学员
        if (studentService.changeStage(student.getId(), 2, true)) {
            return AjaxResult.success("操作成功");
        } else {
            return AjaxResult.error("操作失败");
        }
    }

    // 转为 历史的
    @Log(title = "报读学员转历史学员", businessType = BusinessType.CLEAN)
    @PostMapping("/changeGraduation")
    public AjaxResult changeGraduation(@RequestBody Student student) {
          String s = studentService.changeStageHisyory(student);
                return AjaxResult.success(s);

    }


    @ApiOperation("变为线索学员")
    @PostMapping("/changeIntention")
    public AjaxResult changeIntention(@RequestBody Student student) {
        if (studentService.changeStage(student.getId(), 1, true)) {
            return AjaxResult.success();
        } else {
            return AjaxResult.error("操作失败");
        }
    }

    /**
     * 列表模糊查询下拉列表
     * 学生来源
     */
    @PostMapping("/resource")
    public AjaxResult resource() {
        List<Student> list = studentService.list();
        ArrayList<Object> list1 = new ArrayList<>();
        for (Student student : list) {
            HashMap<Object, Object> map = new HashMap<>();
            map.put("label", student.getJoinWay());
            map.put("value", student.getId());
            list1.add(map);
        }
        return success(list1);
    }


    /**
     * 班级名称
     *
     * @return
     */
    @PostMapping("/classList")
    public AjaxResult classList(@RequestBody StudentClass tClass) {
        tClass.setOrgId(Long.parseLong(loginDeptAuth()));
        LambdaQueryWrapper<StudentClass> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StudentClass::getOrgId, tClass.getOrgId());
        List<StudentClass> list = classService.list(wrapper);
        ArrayList<Object> list1 = new ArrayList<>();
        for (StudentClass classes : list) {
            HashMap<Object, Object> map = new HashMap<>();
            map.put("value", classes.getId());
            map.put("label", classes.getName());
            list1.add(map);
        }
        return success(list1);
    }

    /**
     * 年级列表
     *
     * @return
     */
    @PostMapping("/gradeList")
    public AjaxResult gradeList() {
        List<StudentClassGrade> list = classGradeService.list();
        ArrayList<Object> list1 = new ArrayList<>();
        for (StudentClassGrade classGrade : list) {
            HashMap<Object, Object> map = new HashMap<>();
            map.put("value", classGrade.getId());
            map.put("label", classGrade.getName());
            list1.add(map);
        }
        return success(list1);
    }

    /**
     * 班级课程关联列表
     */
    @PostMapping("/classCourseList")
    public AjaxResult classCourseList(@RequestBody StudentClass tClass) {
        tClass.setOrgId(Long.parseLong(loginDeptAuth()));
     StudentClass list = studentClassService.classCourseList(tClass);
     return AjaxResult.success(list);
    }




    /**
     * 删除线索学员  彻底删除 还原
     */

    @ApiOperation("删除线索学员")
    @PostMapping("/deleteClue")
    public AjaxResult delete(@RequestBody Student student) {
        studentService.deleteClue(student);
        return success("操作成功");
    }



    // 分配跟进人，学管师
    @PostMapping("/getCounselor")
    public AjaxResult getCounselor(@RequestBody Student student) {
        studentService.getCounselor(student);
        return AjaxResult.success("分配成功");
    }

    /**
     * 报读情况列表
     *
     * @return
     */
    @GetMapping("/enrollmentStatus")
    public TableDataInfo enrollmentStatus(EnrollmentStuDto student) {
        long orgId = Long.parseLong(loginDeptAuth());
        //        1, 意向学员 2, 在学学员 3 结业学员 4.报读学员 5.历史学员
        startPage();
        student.setOrgId(orgId);
        List<EnrollmentStuDto> list = studentService.enrollmentList(student);
        return getDataTable(list);
    }


    // 统计剩余课时，剩余金额
    @PostMapping("/remainderCount")
    public AjaxResult remainderCount(@RequestBody EnrollmentStuDto student) {
        long orgId = Long.parseLong(loginDeptAuth());
        student.setOrgId(orgId);
        EnrollmentStuDto remainderCount =  studentService.remainderCount(student);
        return AjaxResult.success(remainderCount);
    }


    @RequestMapping("/enrollExport")
    public void enrollExport(@RequestBody EnrollmentStuDto student, HttpServletResponse response) {
        //1.查询数据
        // 2在读 5历史
        long orgId = Long.parseLong(loginDeptAuth());
        student.setOrgId(orgId);
        List<EnrollmentStuDto> list = studentService.enrollmentList(student);

        //2.封装成表格
        //参数1：表格标题，参数2：sheet名称
        ExportParams exportParams = new ExportParams(null, "报读情况导出");
        //参数1：表格参数  参数2：实体类  参数3：数据
        Workbook sheets = ExcelExportUtil.exportExcel(exportParams, EnrollmentStuDto.class, list);
        //3.返回表格
        //设置表格文件名字
        String fileName = "报读情况导出";
        try {
            fileName = URLEncoder.encode(fileName, "UTF8");
            //设置返回数据类型
            response.setHeader("Access-Control-Expose-Headers", "content-disposition");
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xls");

            //将表格输出
            OutputStream os = response.getOutputStream();
            sheets.write(os);
            os.close();
            os.flush();
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 跟进管理 添加和修改跟进记录
     *
     * @param
     * @param
     * @return
     */
    @Log(title = "跟进管理 添加和修改跟进记录", businessType = BusinessType.UPDATE)
    @PostMapping("/followSave")
    public AjaxResult followSave(@RequestBody StudentContactRecord studentContactRecord) {
        studentContactRecord.setOrgId(Long.parseLong(loginDeptAuth()));
        studentContactRecord.setCounselorId(String.valueOf(getUserId()));
        if (studentContactRecordService.saveOrUpdateByRecord(studentContactRecord)) {
            return AjaxResult.success("操作成功");
        } else {
            return AjaxResult.error("操作失败");
        }
    }

    /**
     * 删除跟进记录
     *
     * @param studentContactRecord
     * @return
     */
    @Log(title = "删除跟进记录", businessType = BusinessType.DELETE)
    @PostMapping("/followDelete")
    @Transactional
    public AjaxResult followDelete(@RequestBody StudentContactRecord studentContactRecord) {
        long id = studentContactRecord.getId();
        StudentContactRecord byId = studentContactRecordService.getById(id);
        long studentId = byId.getStudentId();
        Student student = studentService.getById(studentId);
//        student.setStage(5);
        student.setDeleted(1);
        studentService.updateById(student);
        UpdateWrapper<StudentContactRecord> up=new UpdateWrapper();
        up.set("deleted",1);
        up.eq("student_id",studentId);
        studentContactRecordService.update(up);
        return AjaxResult.success("删除成功");
    }



    /**
     * 删除跟进记录
     *
     * @param studentContactRecord
     * @return
     */
    @Log(title = "删除跟进记录", businessType = BusinessType.DELETE)
    @PostMapping("/followDeleteRecord")
    @Transactional
    public AjaxResult followDeleteRecord(@RequestBody StudentContactRecord studentContactRecord) {
        long id = studentContactRecord.getId();
        StudentContactRecord byId = studentContactRecordService.getById(id);
        byId.setDeleted(1);
        studentContactRecordService.updateById(byId);
        return AjaxResult.success("删除成功");
    }

    /**
     * 一个人的跟进列表 有stuentId
     *
     * @param studentContactRecord
     * @return
     */
    @PostMapping("/followListById")
    public AjaxResult followListById(@RequestBody StudentContactRecord studentContactRecord) {
        studentContactRecord.setOrgId(Long.parseLong(loginDeptAuth()));
        List<StudentContactRecord> list = studentContactRecordService.followListById(studentContactRecord);
        return AjaxResult.success(list);
    }

    /**
     * 跟进管理大列表
     *
     * @param studentContactRecord
     * @return
     */
    @GetMapping("/followList")
    public TableDataInfo followList(StudentContactRecord studentContactRecord) {
        // 机构id
        studentContactRecord.setOrgId(Long.parseLong(loginDeptAuth()));
        startPage();
        List<StudentContactRecord> records = studentContactRecordService.followList(studentContactRecord);
        return getDataTable(records);
    }
//
//    /**
//     * 线索管理的跟进
//     */
//    @PostMapping("/cluefollow")
//    public AjaxResult followList(@RequestBody Student student) {
//        Student stu =  studentService.followList(student);
//        return success(stu);
//    }




    /**
     * 导出报读信息模板
     *
     * @param
     * @param
     * @return
     */
    @ApiOperation("导出模板")
    @GetMapping("/exportInfo")
    public void enrollTemplate(HttpServletResponse response ,@RequestParam(value = "stage") Integer
            stage) {
//        报读学员信息导入
        if (stage == 4) {
            importExportService.exportExcel(response, enrollexcelHeaderMap(), null, "学员报读导入模板");
        }
        // 在读学员基本信息
        if (stage == 2) {
            importExportService.exportExcel(response, excelHeaderMap(), null, "学员基本信息导入模板");
        }
    }

    private Map<String, String> enrollexcelHeaderMap() {
        return new LinkedHashMap<String, String>() {{
            put("studentId", "*学生编号");
            put("name", "*姓名");
            put("mobile", "*手机号");
            put("gender", "性别(有效值:男|女|未知)");
            put("age", "学员年龄");
            put("courseName", "课程名称");
            put("className", "班级名称");
            put("countLessonTotal", "总购买数量");
            put("freeClassHours", "赠送数量");
            put("countLessonComplete", "已消耗数量");
            put("countLessonRefund", "退转数量");
            put("remainderLesson", "剩余课时");
            put("spendAmount", "课消金额");
            put("remainderAmount", "剩余课消金额");
            put("unitPrice", "单价");
            put("courseAmount", "总价");
            put("amount", "应收金额");
            put("paidAmount", "实付金额");
            put("remark", "备注");
        }};
    }

    private Map<String, String> excelHeaderMap() {
        return new LinkedHashMap<String, String>() {{
            put("id", "学生序号");
            put("name", "*姓名");
            put("mobile", "*手机号");
            put("parent", "家长姓名");
            put("gender", "性别(有效值:男|女|未知)");
            put("birthday", "生日(格式:2000-01-01)");
            put("age", "学员年龄");
            put("idcard", "身份证");
            put("joinWay", "学生来源");
            put("remark", "备注");
        }};
    }




    /**
     * 基本信息导入和报读信息导入
     *
     * @param file
     * @param stage
     * @return
     */
    @ApiOperation("导入")
    @PostMapping("/import")
    public AjaxResult importExcel(@RequestParam("file") MultipartFile file, @RequestParam(value = "stage") Integer
            stage) {
        // 导入在读学员信息
        if (stage == 2) {
            List<Map<String, Object>> importDate = importExportService.importExcel(file, excelHeaderMap());
            if (importDate == null || importDate.size() == 0) {
                return AjaxResult.error("未导入数据");
            }
            if (ImportExportService.isRowNotUnique(importDate, "name")) {
                return AjaxResult.error("无法导入:姓名有重复");
            }
            if (ImportExportService.isRowNotUnique(importDate, "mobile")) {
                return AjaxResult.error("无法导入:手机号码有重复");
            }

            List<Student> records = new ArrayList<>();
            for (Map<String, Object> map : importDate) {
                if (map.get("name") == null) {
                    return AjaxResult.error("无法导入:缺少姓名");
                }
                if (map.get("mobile") == null) {
                    return AjaxResult.error("无法导入:" + map.get("name") + "缺少手机号");
                }

                String name = map.get("name").toString().trim();
                String idcard = map.get("idcard") != null ? map.get("idcard").toString().trim() : null;

                LocalDate birthday = null;
                if (map.get("birthday") != null && StringUtils.isNotBlank(map.get("birthday").toString())) {
                    DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                    birthday = LocalDateTime.parse(map.get("birthday").toString(), df).toLocalDate();
                }

                StudentStageEnum stageEnum = EnumTools.getByCode(stage, StudentStageEnum.class);
                if (stageEnum == null) {
                    stageEnum = StudentStageEnum.STUDYING;
                }
                Long staffId = UserAuthUtil.getCurrentUserId();

                Student item = new Student();
                item.setName(name);
                item.setUserId(0L);
                item.setStage(stage);
                item.setBirthday(birthday);
                item.setIdcard(idcard);
                item.setCounselorId(staffId);
                records.add(item);
            }
            return studentService.saveBatch(records) ?
                    AjaxResult.success("成功导入" + importDate.size() + "条记录") :
                    AjaxResult.error("导入出错");
        }
        if (stage == 4){
            // 报读信息导入
            List<Map<String, Object>> importDate = importExportService.importExcel(file, enrollexcelHeaderMap());
            if (importDate == null || importDate.size() == 0) {
                return AjaxResult.error("未导入数据");
            }

            List<StudentCourse> records = new ArrayList<>();
            for (Map<String, Object> map : importDate) {
                String mobile = map.get("mobile").toString().trim();
                String name = map.get("name").toString().trim();
                String courseName = map.get("courseName").toString().trim();
                String gender = map.get("gender").toString().trim();
                String age = map.get("age").toString().trim();
                String className = map.get("className").toString().trim();
                String studentId = map.get("studentId").toString().trim();
                int countLessonTotal = Integer.parseInt( map.get("countLessonTotal").toString().trim());
                int freeClassHours = Integer.parseInt(map.get("freeClassHours").toString().trim());
                int countLessonComplete = Integer.parseInt(map.get("countLessonComplete").toString().trim());
                int countLessonRefund = Integer.parseInt(map.get("countLessonRefund").toString().trim());
                int remainderLesson = Integer.parseInt(map.get("remainderLesson").toString().trim());
                int spendAmount = Integer.parseInt(map.get("spendAmount").toString().trim());
                BigDecimal unitPrice = new  BigDecimal(map.get("unitPrice").toString().trim());
                BigDecimal courseAmount = new  BigDecimal(map.get("courseAmount").toString().trim());
                Object amount1 = map.get("amount");
                BigDecimal amount = getBigDecimal(amount1);
                Object paidAmount1 =  map.get("paidAmount");
                BigDecimal paidAmount = getBigDecimal(paidAmount1);
                String remark = map.get("remark").toString().trim();

                StudentCourse item = new StudentCourse();
                item.setName(name);
                item.setStudentId(Long.valueOf(studentId));
                item.setMobile(mobile);
                item.setCourseName(courseName);
                item.setGender(gender);
                item.setAge(age);
                item.setClassName(className);
                item.setCountLessonTotal(countLessonTotal);
                item.setCountLessonTotalGive(freeClassHours);
                item.setCountLessonComplete(countLessonComplete);
                item.setCountLessonRefund(countLessonRefund);
                item.setRemainderLesson(remainderLesson);
                item.setSpendAmount(spendAmount);
                item.setUnitPrice(unitPrice);
                item.setCourseAmount(courseAmount);
                item.setAmount(amount);
                item.setPaidAmount(paidAmount);
                item.setRemark(remark);
                records.add(item);
            }
            return studentCourseService.saveBatch(records) ?
                    AjaxResult.success("成功导入" + importDate.size() + "条记录") :
                    AjaxResult.error("导入出错");
        }
        return AjaxResult.success("导入成功");
    }
    /**
     * Object转BigDecimal类型
     *
     * @param value 要转的object类型
     * @return 转成的BigDecimal类型数据
     */
    public static BigDecimal getBigDecimal(Object value) {
        BigDecimal ret = null;
        if (value != null) {
            if (value instanceof BigDecimal) {
                ret = (BigDecimal) value;
            } else if (value instanceof String) {
                ret = new BigDecimal((String) value);
            } else if (value instanceof BigInteger) {
                ret = new BigDecimal((BigInteger) value);
            } else if (value instanceof Number) {
                ret = new BigDecimal(((Number) value).doubleValue());
            } else {
                throw new ClassCastException("Not possible to coerce [" + value + "] from class " + value.getClass() + " into a BigDecimal.");
            }
        }
        return ret;
    }


    /**
     * 导出 在读
     *
     * @param
     * @param response
     */

    @RequestMapping("/export")
    public void export(@RequestBody Student student, HttpServletResponse response) {
        student.setSize(999999999l);
        student.setCurrent(1l);
        //1.查询数据
        // 2在读 5历史
        student.setOrgId(Long.parseLong(loginDeptAuth()));
        List<Student> list = studentService.getList(student);
        //2.封装成表格
        //参数1：表格标题，参数2：sheet名称
        ExportParams exportParams = new ExportParams(null, "在读学员导出");

        //参数1：表格参数  参数2：实体类  参数3：数据
        Workbook sheets = ExcelExportUtil.exportExcel(exportParams, Student.class, list);
        //3.返回表格
        //设置表格文件名字
        String fileName = "在读学员导出";
        try {
            fileName = URLEncoder.encode(fileName, "UTF8");
            //设置返回数据类型
            response.setHeader("Access-Control-Expose-Headers", "content-disposition");
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xls");

            //将表格输出
            OutputStream os = response.getOutputStream();
            sheets.write(os);
            os.close();
            os.flush();
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 成长档案
     *
     * @param student
     * @return
     */
//    @PostMapping("/growthPortfolio")
//    public AjaxResult growthPortfolio(@RequestBody Student student) {
//        List<StudentAdvertisement> list = studentAdvertismentService.getAll(student);
//        return list;
//    }
//

}

